#include "User.h"

//Contructor
//@author U095387X
User::User() {
	_userAccount = Account();
}

//@author U095387X
User::User( string name, double budget, double cashOnHand){
	_name = name;
	_budget = budget;
	_totalExpense = 0;
	_cashOnHand = cashOnHand;
	time (&_lastUsed); 
	saveUser();
}

//Getter
//@author A0088381W
void User::loadUser(){

	string name, sBudget, sCashOnHand, sTotalExpense, sLastTime;
	time_t currentTime, lastTime;
	time(&currentTime);

	ifstream readFile("User.txt");
	getline(readFile, name);
	_name = name;
	getline(readFile, sBudget);
	_budget = atof(sBudget.c_str());
	getline(readFile, sCashOnHand);
	_cashOnHand = atof(sCashOnHand.c_str());
	getline(readFile, sTotalExpense);
	_totalExpense = atof(sTotalExpense.c_str());
	getline(readFile, sLastTime);
	lastTime = atoi(sLastTime.c_str());
	time (&_lastUsed);
	readFile.close();

	list<Loan> loanList = _userAccount.readLoan();
	if ( !loanList.empty()) {
		struct tm * lastTimeInfo;
		struct tm * currentTimeInfo;

		lastTimeInfo = localtime(&lastTime);
		int lastMonth = lastTimeInfo->tm_mon;
		int lastYear = lastTimeInfo->tm_year;
		currentTimeInfo = localtime (&currentTime);
		int thisMonth = currentTimeInfo->tm_mon;
		int thisYear = currentTimeInfo->tm_year;

		int monthPass;
		monthPass =	(thisYear - lastYear)*12 + (thisMonth - lastMonth);

		if (monthPass > 0 ) {
			_totalExpense = 0;
			for ( int i = 0; i < monthPass; i++) {
				list<Loan>::iterator iter = loanList.begin();
				while (iter != loanList.end()) {
					string name = iter->getName();
					double amount = iter->getAmount();
					time_t timeOfRecord, inputTime;
					time(&timeOfRecord);
					time(&inputTime);
					e_method mMethod = Cash;
					e_category mCategory = Others;
					string remark = "Monthly Deducted Loan";
					Expense newExpense(name,amount,timeOfRecord,inputTime,mMethod,mCategory,remark);
					addExpense(newExpense);
					iter++;
				}
			}
		}
	}
	saveUser();
}

//@author U095387X
bool User::existUser(){
	ifstream UserFile("User.txt");
	if (UserFile.good())
		return true;
	else
		return false;
}

//@author U095387X
string User::getName(){
	return _name;	
}

//@author U095387X
double User::getBudget(){
	return _budget;
}

//@author U095387X
double User::getCashOnHand(){
	return _cashOnHand;
}

//@author A0088381W
double User::getTotalExpense() {
	return _totalExpense;
}

//@author U095387X
Account *User::getUserAccount(){
	//_userAccount = Account();
	return &_userAccount;
}

//@author A0088381W
time_t User::getLastUsed() {
	return _lastUsed;
}

//@author U095387X
void User::updateName( string newName ){
	_name = newName;
	saveUser();
	return;
}

//@author U095387X
void User::updateCashOnHand( double newCashOnHand ){
	_cashOnHand = newCashOnHand;
	saveUser();
	return;
}

//@author U095387X
void User::updateBudget( double newBudget ){
	_budget = newBudget;
	saveUser();
	return;
}


//@author A0088381W
void User::updateTotalExpense(double newTotalExpense) {
	_totalExpense = newTotalExpense;
	saveUser();
	return;
}

//@author U095387X
void User::addExpense(Expense newExpense) {
	_userAccount.addExpense(newExpense);
	_cashOnHand -= newExpense.getAmount();

	time_t timeExpense = newExpense.getTimeOfRecord();
	time_t rawTime;
	time(&rawTime);
	struct tm * timeInfo;
	struct tm * rawTimeInfo;
	timeInfo = localtime(&timeExpense);
	int expenseMonth = timeInfo->tm_mon;
	int expenseYear = timeInfo->tm_year;
	rawTimeInfo = localtime(&rawTime);
	int thisMonth = rawTimeInfo->tm_mon;
	int thisYear = rawTimeInfo->tm_year;
	int monthPass =	(thisYear - expenseYear)*12 + (thisMonth - expenseMonth);
	if ( monthPass == 0 ) {
		_totalExpense += newExpense.getAmount();
	}
	saveUser();
}

//@author U095387X
void User::addIncome(Income newIncome) {
	_userAccount.addIncome(newIncome);
	_cashOnHand += newIncome.getAmount();
	saveUser();
}

//@author U095387X
void User::addLoan(Loan newLoan) {
	_userAccount.addLoan(newLoan);
	saveUser();
}

//@author U095387X
void User::addWish(Wish newWish) {
	_userAccount.addWish(newWish);
	saveUser();
}

//@author A0088381W
void User::deleteExpense(Expense expenseToDelete) {
	_userAccount.deleteExpense(expenseToDelete);
	_cashOnHand += expenseToDelete.getAmount();

	time_t timeExpense = expenseToDelete.getTimeOfRecord();
	time_t rawTime;
	time(&rawTime);
	struct tm * timeInfo;
	struct tm * rawTimeInfo;
	timeInfo = localtime(&timeExpense);
	int expenseMonth = timeInfo->tm_mon;
	int expenseYear = timeInfo->tm_year;
	rawTimeInfo = localtime(&rawTime);
	int thisMonth = rawTimeInfo->tm_mon;
	int thisYear = rawTimeInfo->tm_year;
	int monthPass =	(thisYear - expenseYear)*12 + (thisMonth - expenseMonth);
	if ( monthPass == 0 ) {
		_totalExpense -= expenseToDelete.getAmount();
	}

	saveUser();
}

//@author A0088381W
void User::deleteIncome(Income incomeToDelete) {
	_userAccount.deleteIncome(incomeToDelete);
	_cashOnHand -= incomeToDelete.getAmount();
	saveUser();
}

//@author A0088381W
void User::deleteLoan(Loan loanToDelete) {
	_userAccount.deleteLoan(loanToDelete);
	saveUser();
}

//@author A0088381W
void User::deleteWish(Wish wishToDelete) {
	_userAccount.deleteWish(wishToDelete);
	saveUser();
}

//@author U095387X
void User::updateExpense(Expense expenseToDelete, Expense newExpense){
	deleteExpense(expenseToDelete);
	addExpense(newExpense);
}

//@author U095387X
void User::updateIncome(Income incomeToDelete, Income newIncome){
	deleteIncome(incomeToDelete);
	addIncome(newIncome);
}

//@author U095387X
void User::updateWish(Wish wishToDelete, Wish newWish){
	deleteWish(wishToDelete);
	addWish(newWish);
}

//@author U095387X
void User::updateLoan(Loan loanToDelete, Loan newLoan){
	deleteLoan(loanToDelete);
	addLoan(newLoan);
}

//@author U095387X
void User::saveUser() {
	ofstream writeFile("User.txt");
	writeFile << _name << endl;
	writeFile << _budget << endl;
	writeFile << _cashOnHand << endl;
	writeFile << _totalExpense << endl;
	writeFile << _lastUsed << endl;
	writeFile.close();
}